﻿Option Strict On
Option Explicit On

Imports System.Drawing

''' <summary>
''' Represents a simple circle expressed as a center location and radius.
''' </summary>
''' <remarks></remarks>
Public Structure Circle
    Public Shared ReadOnly Empty As New Circle

    ''' <summary>
    ''' Gets a value indicating if two circles intersect.
    ''' </summary>
    ''' <param name="source">The source circle to test for intersection.</param>
    ''' <param name="target">The target circle to test intersection with.</param>
    ''' <returns>True if the circles intersect, otherwise false.</returns>
    ''' <remarks></remarks>
    Public Shared Function Intersects(ByVal source As Circle, ByVal target As Circle) As Boolean
        Dim centerDistance As Single = Vector2.GetDistance(source.Origin, target.Origin)
        Dim radiusTotal As Single = source.Radius + target.Radius
        Return radiusTotal > centerDistance
    End Function

    ''' <summary>
    ''' Gets or sets the circle's center location.
    ''' </summary>
    ''' <remarks></remarks>
    Public Origin As Vector2
    ''' <summary>
    ''' Gets or sets the circle's radius.
    ''' </summary>
    ''' <remarks></remarks>
    Public Radius As Single

    ''' <summary>
    ''' Gets a rectangle that bounds the circumference of the circle.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Bounds As RectangleF
        Get
            Return New RectangleF(Origin.X - Radius, Origin.Y - Radius, Radius * 2, Radius * 2)
        End Get
    End Property

    ''' <summary>
    ''' Gets the diameter of the circle, which is twice the raidus.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Diameter As Single
        Get
            Return Radius * 2
        End Get
    End Property

    ''' <summary>
    ''' Creates a new circle instance at the specified position and with the specified radius.
    ''' </summary>
    ''' <param name="centerPoint"></param>
    ''' <param name="radiusLength"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal centerPoint As Vector2, ByVal radiusLength As Single)
        Origin = centerPoint
        Radius = radiusLength
    End Sub

    ''' <summary>
    ''' Gets a value indicating whether or not the specified position is contained within the bounds of the circle.
    ''' </summary>
    ''' <param name="position">The position to check.</param>
    ''' <returns>True if the position is within the bounds of the circle, otherwise false.</returns>
    ''' <remarks></remarks>
    Public Function Contains(position As Vector2) As Boolean
        Return Vector2.GetDistance(Origin, position) <= Radius
    End Function

    ''' <summary>
    ''' Gets a GraphicsPath object with this circle positioned in the upper left corner.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetLocalPath() As System.Drawing.Drawing2D.GraphicsPath
        Dim result As New System.Drawing.Drawing2D.GraphicsPath
        Dim dia As Single = Radius * 2
        result.AddEllipse(New RectangleF(0.0F, 0.0F, dia, dia))
        Return result
    End Function

    ''' <summary>
    ''' Gets a GraphicsPath object with this circle positioned at its origin location.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetWorldPath() As System.Drawing.Drawing2D.GraphicsPath
        Dim result As New System.Drawing.Drawing2D.GraphicsPath
        result.AddEllipse(Bounds)
        Return result
    End Function

    ''' <summary>
    ''' Gets a value indicating if this circle intersects with the target circle.
    ''' </summary>
    ''' <param name="target">The circle to test intersection with.</param>
    ''' <returns>True if the circles intersect, otherwise false.</returns>
    ''' <remarks></remarks>
    Public Function IntersectsWith(ByVal target As Circle) As Boolean
        Return Circle.Intersects(Me, target)
    End Function
End Structure